﻿using System;
using System.Linq.Expressions;
using Fuse8.ContentManagementFramework.DataAccess.Contents;
using Fuse8.ContentManagementFramework.DataAccess.SqlAccess;
using Fuse8.ContentManagementFramework.DataAccess.SqlAccess.Commands;
using Fuse8.ContentManagementFramework.DataAccess.SqlAccess.Commands.CmsUser;
using Fuse8.ContentManagementFramework.DataAccess.SqlAccess.Mappers;
using Fuse8.ContentManagementFramework.Domain;
using Fuse8.ContentManagementFramework.Domain.Commands;
using Fuse8.ContentManagementFramework.Domain.Commands.CmsUser;
using Fuse8.ContentManagementFramework.Domain.Special;
using Fuse8.ContentManagementFramework.SystemFacade.Contents;
using Fuse8.DomainFramework.Common.Locator;
using Fuse8.DomainFramework.DataAccess;
using Fuse8.DomainFramework.DataAccess.ExpressionSlicers;
using Fuse8.DomainFramework.DataAccess.SqlDatabase;

namespace Fuse8.ContentManagementFramework.DataAccess
{
    public static class DataAccessPolicy
    {
        public static void Register(Func<Type, string> dataConnectionResolver)
        {
            DependencyServiceLocator.Current.SetDefaultService<IContentSchemeBuilder>(new Sql2008ViewSchemeBuilder());

            if (dataConnectionResolver == null)
            {
                dataConnectionResolver = CmsDataRepositoryConfiguration.DefineConnectionString;
            }

            SetCmsSiteAdminMap(dataConnectionResolver);

            SetCmsSiteGroup(dataConnectionResolver);

            SetCmsSite(dataConnectionResolver);

            SetCmsDomain(dataConnectionResolver);

            SetCmsUserGroup(dataConnectionResolver);

            SetCmsUser(dataConnectionResolver);

            SetCmsUserInformation(dataConnectionResolver);

            SetCmsEntityMetaField(dataConnectionResolver);

            SetCmsEntityMetaFieldLink(dataConnectionResolver);

            SetCmsEntityMeta(dataConnectionResolver);

            SetCmsEntityMetaInformation(dataConnectionResolver);

            SetCmsMimetype(dataConnectionResolver);

            SetCmsMediaContentTag(dataConnectionResolver);

            SetCmsMediaFile(dataConnectionResolver);

            SetCmsMedia(dataConnectionResolver);

            SetCmsMediaContent(dataConnectionResolver);

            SetCmsMediaContentFileLink(dataConnectionResolver);

            SetCmsContentType(dataConnectionResolver);

            SetCmsDashboard(dataConnectionResolver);

            SetCmsTemplate(dataConnectionResolver);

            SetCmsTemplateRegion(dataConnectionResolver);

            SetCmsPage(dataConnectionResolver);

            SetCmsPageControl(dataConnectionResolver);

            SetCmsModule(dataConnectionResolver);

            SetCmsWorkflow(dataConnectionResolver);

            SetCmsWorkflowHistory(dataConnectionResolver);

            SetCmsPageContainer(dataConnectionResolver);

            SetCmsEntityAnnotation(dataConnectionResolver);

            SetCmsEntityAnnotationContainer(dataConnectionResolver);

            SetCmsContent(dataConnectionResolver);

            SetCmsSystemLanguages(dataConnectionResolver);

            SqlEntityHelper.SetSuccessor(new CmsEntityNameMapper());
            SchemaBuilder.SetSuccessor(new CmsEntitySchemeBuilder());

            InitSlicers();

            DependencyServiceLocator.Current.Register(typeof(CmsEntitySearchCommand<>), typeof(CmsEntitySearchDataCommand<>));
        }

        private static void SetCmsSystemLanguages(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register(SqlEntityDataRepositoryConfiguration<CmsSystemLanguage, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsSystemLanguage))));
            container.Register<ISqlEntityDataMapper<CmsSystemLanguage, int>>(new CmsBaseSqlEntityDeepDataMapper<CmsSystemLanguage, int>());
            var repo = SqlEntityDataRepositoryConfiguration<CmsSystemLanguage, int>.CreateMixedRepository();
            container.Register<IEntityDataRepository<CmsSystemLanguage, int>>(repo);
        }

        private static void InitSlicers()
        {
            SlicerServiceFacade.Current.AddDynamic(() =>
                                                     {
                                                         var contextSite =
                                                             DependencyServiceLocator.Current.GetInstance<ICmsContext>().
                                                                 ContextSite;
                                                         Expression<Func<CmsSiteEntityObject, bool>> slicer =
                                                             p =>
                                                             (p.SiteGroupId == null && p.SiteId == null) ||
                                                             (p.SiteGroupId == contextSite.SiteGroupId && p.SiteId == null) ||
                                                             (p.SiteGroupId == contextSite.SiteGroupId &&
                                                              p.SiteId == contextSite.Id);
                                                         return slicer;
                                                     });
            SlicerServiceFacade.Current.Add<IDeletableEntity>(p => !p.IsDeleted);
        }

        private static void SetCmsEntityMetaFieldLink(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsEntityMetaFieldLink>>(
                SqlEntityDataRepositoryConfiguration<CmsEntityMetaFieldLink, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsEntityMetaFieldLink))));
            container.Register<ISqlEntityDataMapper<CmsEntityMetaFieldLink, int>>(new CmsEntityMetaFieldLinkDataMapper());
            var cmsEntityMetaRepository = SqlEntityDataRepositoryConfiguration<CmsEntityMetaFieldLink, int>.CreateRepository();
            cmsEntityMetaRepository.AddSpName = "cms_sp_EntityMetaFieldLinkAdd";
            cmsEntityMetaRepository.UpdateSpName = "cms_sp_EntityMetaFieldLinkSave";
            cmsEntityMetaRepository.FindOneSpName = "cms_sp_EntityMetaFieldLinkSelectOne";
            cmsEntityMetaRepository.RemoveSpName = "cms_sp_EntityMetaFieldLinkDelete";
            container.Register<IEntityDataRepository<CmsEntityMetaFieldLink, int>>(cmsEntityMetaRepository);

            container.Register(typeof(CmsEntityMetaFieldLinkForTypeCommand), typeof(CmsEntityMetaFieldLinkForTypeDataCommand));
        }

        private static void SetCmsContent(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsContentContainer>>(
                SqlEntityDataRepositoryConfiguration<CmsContentContainer, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsContent))));
            container.Register<IEntityDataRepository<CmsContentContainer, int>>(
                SqlEntityDataRepositoryConfiguration<CmsContentContainer, int>.CreateRepository());
            container.Register<IUnitOfWorkFactory<CmsContent>>(
                SqlEntityDataRepositoryConfiguration<CmsContent, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsContent))));
            container.Register<ISqlEntityDataMapper<CmsContent, int>>(new CmsContentDataMapper());
            var cmsContentRepository = SqlEntityDataRepositoryConfiguration<CmsContent, int>.CreateRepository();
            cmsContentRepository.FindOneSpName = "cms_sp_ContentSelectOne";
            cmsContentRepository.AddSpName = "cms_sp_Content_Add";
            cmsContentRepository.UpdateSpName = "cms_sp_Content_Save";
            cmsContentRepository.RemoveSpName = "cms_sp_Content_Delete";
            cmsContentRepository.FindAllSpName = "cms_sp_ContentSelectAll";
            cmsContentRepository.FindParameters =
                    (sp, defaultParams) =>
                    {
                        object result = null;

                        var contextSite = DependencyServiceLocator.Current.GetInstance<ICmsContext>().ContextSite;

                        if (!string.IsNullOrEmpty(sp))
                        {
                            if (sp.Equals(cmsContentRepository.FindAllSpName, StringComparison.OrdinalIgnoreCase))
                            {
                                result = new { SiteGroupId = contextSite.SiteGroupId, SiteId = contextSite.Id };
                            }
                        }

                        return result ?? defaultParams;
                    };
            container.Register<IEntityDataRepository<CmsContent, int>>(cmsContentRepository);
            container.Register(typeof(CmsContentGetForContentTypeCommand), typeof(CmsContentGetForContentTypeDataCommand));

            container.Register(SqlEntityDataRepositoryConfiguration<GenericCmsEntity, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsContent))));
            container.Register<ISqlEntityDataMapper<GenericCmsEntity, int>>(new CmsBaseSqlEntityDeepDataMapper<GenericCmsEntity, int>());
        }

        private static void SetCmsEntityAnnotation(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsEntityAnnotation>>(
                SqlEntityDataRepositoryConfiguration<CmsEntityAnnotation, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsEntityAnnotation))));
            container.Register<ISqlEntityDataMapper<CmsEntityAnnotation, int>>(new CmsEntityAnnotationDataMapper());
            var cmsEntityAnnotationDataRepository = SqlEntityDataRepositoryConfiguration<CmsEntityAnnotation, int>.CreateRepository();
            container.Register<IEntityDataRepository<CmsEntityAnnotation, int>>(cmsEntityAnnotationDataRepository);
            container.Register(typeof(CmsEntityAnnotationGetForEntityCommand), typeof(CmsEntityAnnotationGetForEntityDataCommand));
            container.Register(typeof(CmsEntityAnnotationSaveForEntityCommand), typeof(CmsEntityAnnotationSaveForEntityDataCommand));
        }

        private static void SetCmsPageContainer(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsPageContainer>>(
                SqlEntityDataRepositoryConfiguration<CmsPageContainer, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsPageContainer))));

            container.Register<ISqlEntityDataMapper<CmsPageContainer, int>>(new CmsPageContainerDataMapper());
        }

        private static void SetCmsEntityAnnotationContainer(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsEntityAnnotationContainer>>(
                SqlEntityDataRepositoryConfiguration<CmsEntityAnnotationContainer, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsEntityAnnotationContainer))));

            container.Register<ISqlEntityDataMapper<CmsEntityAnnotationContainer, int>>(new CmsEntityAnnotationContainerDataMapper());
        }

        private static void SetCmsWorkflowHistory(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsWorkflowHistory>>(
                SqlEntityDataRepositoryConfiguration<CmsWorkflowHistory, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsWorkflowHistory))));
            container.Register<ISqlEntityDataMapper<CmsWorkflowHistory, int>>(
                SqlEntityDataRepositoryConfiguration<CmsWorkflowHistory, int>.CreateMapper(new string[] { "Workflow", "AssignedUser", "AssignedUserGroup" }));
            var cmsWorkflowHistoryRepository = SqlEntityDataRepositoryConfiguration<CmsWorkflowHistory, int>.CreateRepository();
            cmsWorkflowHistoryRepository.AddSpName = "cms_sp_WorkflowHistoryAdd";
            container.Register<IEntityDataRepository<CmsWorkflowHistory, int>>(cmsWorkflowHistoryRepository);
        }

        private static void SetCmsWorkflow(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsWorkflow>>(
                SqlEntityDataRepositoryConfiguration<CmsWorkflow, Guid>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsWorkflow))));
            container.Register<ISqlEntityDataMapper<CmsWorkflow, Guid>>(new CmsWorkflowDataMapper());
            var cmsWorkflowRepository = SqlEntityDataRepositoryConfiguration<CmsWorkflow, Guid>.CreateRepository();
            cmsWorkflowRepository.AddSpName = "cms_sp_WorkflowAdd";
            cmsWorkflowRepository.FindOneSpName = "cms_sp_WorkflowSelectOne";
            container.Register<IEntityDataRepository<CmsWorkflow, Guid>>(cmsWorkflowRepository);
            container.Register(typeof(CmsWorkflowSelectOneCommand), typeof(CmsWorkflowSelectOneDataCommand));
        }

        private static void SetCmsModule(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsModule>>(
                SqlEntityDataRepositoryConfiguration<CmsModule, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsModule))));
            container.Register<ISqlEntityDataMapper<CmsModule, int>>(
                SqlEntityDataRepositoryConfiguration<CmsModule, int>.CreateMapper(
                    new string[] { "SiteGroup", "Site", "SiteCategory", "EntityMetaInformation", "Metas" }));
            var cmsModuleDataRepository = SqlEntityDataRepositoryConfiguration<CmsModule, int>.CreateRepository();
            cmsModuleDataRepository.FindOneSpName = "cms_sp_ModuleSelectOne";
            cmsModuleDataRepository.AddSpName = "cms_sp_ModuleAdd";
            cmsModuleDataRepository.UpdateSpName = "cms_sp_ModuleSave";
            cmsModuleDataRepository.RemoveSpName = "cms_sp_ModuleDelete";
            container.Register<IEntityDataRepository<CmsModule, int>>(cmsModuleDataRepository);
            container.Register(typeof(CmsModuleSelectAllCommand), typeof(CmsModuleSelectAllDataCommand));
        }

        private static void SetCmsPageControl(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsPageControl>>(
                SqlEntityDataRepositoryConfiguration<CmsPageControl, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsPageControl))));
            container.Register<ISqlEntityDataMapper<CmsPageControl, int>>(new CmsPageControlDataMapper());
            var cmsPageControlDataRepository = SqlEntityDataRepositoryConfiguration<CmsPageControl, int>.CreateRepository();
            cmsPageControlDataRepository.AddSpName = "cms_sp_PageControlAdd";
            cmsPageControlDataRepository.FindOneSpName = "cms_sp_PageControlSelectOne";
            cmsPageControlDataRepository.UpdateSpName = "cms_sp_PageControlSave";
            cmsPageControlDataRepository.RemoveSpName = "cms_sp_PageControlDelete";
            container.Register<IEntityDataRepository<CmsPageControl, int>>(cmsPageControlDataRepository);
            container.Register(typeof(CmsPageControlMoveCommand), typeof(CmsPageControlMoveDataCommand));
            container.Register(typeof(CmsPageAddControlCommand), typeof(CmsPageAddControlDataCommand));
            container.Register(typeof(CmsUpdatePageControlCommand), typeof(CmsUpdatePageControlDataCommand));
            container.Register(typeof(CmsPageControlsGetByPageIdCommand), typeof(CmsPageControlsGetByPageIdDataCommand));
            container.Register(typeof(CmsPageControlsChangeTemplateRegionsCommand), typeof(CmsPageControlsChangeTemplateRegionsDataCommand));
        }

        private static void SetCmsPage(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsPage>>(
                SqlEntityDataRepositoryConfiguration<CmsPage, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsPage))));
            container.Register<ISqlEntityDataMapper<CmsPage, int>>(new CmsPageDataMapper());
            container.Register<ISqlEntityDataMapper<CmsPageCounts, int>>(new BaseSqlEntityDataMapper<CmsPageCounts, int>());
            var cmsPageDataRepository = SqlEntityDataRepositoryConfiguration<CmsPage, int>.CreateRepository();
            cmsPageDataRepository.AddSpName = "cms_sp_PageAdd";
            cmsPageDataRepository.UpdateSpName = "cms_sp_PageSave";
            cmsPageDataRepository.RemoveSpName = "cms_sp_PageDelete";
            cmsPageDataRepository.FindOneSpName = "cms_sp_PageSelectOne";
            cmsPageDataRepository.FindAllSpName = "cms_sp_PageSelectAll";
            container.Register<IEntityDataRepository<CmsPage, int>>(cmsPageDataRepository);
            container.Register(typeof(CmsPageTypeResolverCommand), typeof(CmsPageTypeResolverDataCommand));
            container.Register(typeof(CmsPageFrontEndCommand), typeof(CmsPageFrontEndDataCommand));
            container.Register(typeof(CmsPageSelectOneCommand), typeof(CmsPageSelectOneDataCommand));
            container.Register(typeof(CmsPageSelectAllCommand), typeof(CmsPageSelectAllDataCommand));
            container.Register(typeof(CmsPagePreviewCommand), typeof(CmsPagePreviewDataCommand));
            container.Register(typeof(CmsPageReallocateCommand), typeof(CmsPageReallocateDataCommand));
            container.Register(typeof(CmsPageMoveCommand), typeof(CmsPageMoveDataCommand));
            container.Register(typeof(CmsPageSelectFamilyPagesCommand), typeof(CmsPageSelectFamilyPagesDataCommand));
            container.Register(typeof(CmsEntityGetAllRevisionsCommand<CmsPage>), typeof(CmsPageGetAllRevisionsCommand));
            container.Register(typeof(CmsEntityGetAllWorkflowNotesCommand<CmsPage>), typeof(CmsPageGetAllWorkflowNotesDataCommand));
            container.Register(typeof(CmsEntityGetDraftRevisionsCommand<CmsPage>), typeof(CmsPageGetDraftRevisionsDataCommand));
            container.Register(typeof(CmsEntityRevisionUpdateCommand<CmsPage>), typeof(CmsPageRevisionUpdateDataCommand));
            container.Register(typeof(CmsEntityGetActiveRevisionsCommand<CmsPage>), typeof(CmsPageGetActiveRevisionsDataCommand));
            container.Register(typeof(CmsEntityGetApprovedRevisionsCommand<CmsPage>), typeof(CmsPageGetApprovedRevisionsDataCommand));
            container.Register(typeof(CmsPageSaveCommand), typeof(CmsPageSaveDataCommand));
            container.Register(typeof(CmsPageCopyCommand), typeof(CmsPageCopyDataCommand));

            container.Register(SqlEntityDataRepositoryConfiguration<CmsPageCounts, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsPageCounts))));
            container.Register<IEntityDataRepository<CmsPageCounts, int>>(SqlEntityDataRepositoryConfiguration<CmsPageCounts, int>.CreateRepository());
            container.Register(typeof(CmsPageGetCountsCommand), typeof(CmsPageGetCountsDataCommand));

            container.Register(typeof(CmsPageSelectAllByPageKeyCommand), typeof(CmsPageSelectAllByPageKeyDataCommand));
            container.Register(typeof(CmsPageSelectAllByTemplateIdCommand), typeof(CmsPageSelectAllByTemplateIdDataCommand));
        }

        private static void SetCmsTemplateRegion(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsTemplateRegion>>(
                SqlEntityDataRepositoryConfiguration<CmsTemplateRegion, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsTemplateRegion))));
            container.Register<ISqlEntityDataMapper<CmsTemplateRegion, int>>(
                SqlEntityDataRepositoryConfiguration<CmsTemplateRegion, int>.CreateMapper(
                    new string[] { "RegionControls", "Template", "HasControls" }));
            var cmsTemplateRegionDataRepository = SqlEntityDataRepositoryConfiguration<CmsTemplateRegion, int>.CreateRepository();
            cmsTemplateRegionDataRepository.AddSpName = "cms_sp_TemplateRegionAdd";
            cmsTemplateRegionDataRepository.FindAllSpName = "cms_sp_TemplateRegionSelectAll";
            container.Register<IEntityDataRepository<CmsTemplateRegion, int>>(cmsTemplateRegionDataRepository);
        }

        private static void SetCmsTemplate(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsTemplate>>(
                SqlEntityDataRepositoryConfiguration<CmsTemplate, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsTemplate))));
            container.Register<ISqlEntityDataMapper<CmsTemplate, int>>(new CmsTemplateDataMapper());
            var cmsTemplateDataRepository = SqlEntityDataRepositoryConfiguration<CmsTemplate, int>.CreateRepository();
            cmsTemplateDataRepository.AddSpName = "cms_sp_TemplateAdd";
            cmsTemplateDataRepository.RemoveSpName = "cms_sp_TemplateDelete";
            cmsTemplateDataRepository.UpdateSpName = "cms_sp_TemplateSave";
            cmsTemplateDataRepository.FindOneSpName = "cms_sp_TemplateSelectOne";
            container.Register<IEntityDataRepository<CmsTemplate, int>>(cmsTemplateDataRepository);
            container.Register(typeof(CmsTemplateSelectAllCommand), typeof(CmsTemplateSelectAllDataCommand));
            container.Register(typeof(CmsTemplateSelectOneCommand), typeof(CmsTemplateSelectOneDataCommand));
        }

        private static void SetCmsDashboard(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsDashboard>>(
                SqlEntityDataRepositoryConfiguration<CmsDashboard, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsDashboard))));
            var cmsDashboardDataRepository = SqlEntityDataRepositoryConfiguration<CmsDashboard, int>.CreateRepository();
            cmsDashboardDataRepository.FindAllSpName = "cms_sp_DashboardSelectAll";
            container.Register<IEntityDataRepository<CmsDashboard, int>>(cmsDashboardDataRepository);
            container.Register(typeof(CmsDashboardSelectForUserCommand), typeof(CmsDashboardSelectForUserDataCommand));
        }

        private static void SetCmsContentType(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsContentType>>(
                SqlEntityDataRepositoryConfiguration<CmsContentType, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsContentType))));
            container.Register<ISqlEntityDataMapper<CmsContentType, int>>(new CmsBaseSqlEntityDeepDataMapper<CmsContentType, int>());
            var cmsContentTypeRepository =
                SqlEntityDataRepositoryConfiguration<CmsContentType, int>.CreateMixedRepository();
            cmsContentTypeRepository.RemoveSpName = "cms_sp_ContentTypeDelete";
            container.Register<IEntityDataRepository<CmsContentType, int>>(cmsContentTypeRepository);
            container.Register(typeof(CmsContentTypeDeleteCommand), typeof(CmsContentTypeDeleteDataCommand));
        }

        private static void SetCmsMediaContent(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsMediaContent>>(
                SqlEntityDataRepositoryConfiguration<CmsMediaContent, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsMediaContent))));
            container.Register<ISqlEntityDataMapper<CmsMediaContent, int>>(new CmsMediaContentDataMapper());
            var cmsMediaContentRepository = SqlEntityDataRepositoryConfiguration<CmsMediaContent, int>.CreateRepository();
            cmsMediaContentRepository.FindAllSpName = "cms_sp_MediaContentSelectAll";
            cmsMediaContentRepository.AddSpName = "cms_sp_MediaContentAdd";
            cmsMediaContentRepository.UpdateSpName = "cms_sp_MediaContentSave";
            cmsMediaContentRepository.RemoveSpName = "cms_sp_MediaContentDelete";
            cmsMediaContentRepository.FindOneSpName = "cms_sp_MediaContentSelectOne";
            cmsMediaContentRepository.FindParameters =
            (sp, defaultParams) =>
            {
                object result = null;

                var contextSite = DependencyServiceLocator.Current.GetInstance<ICmsContext>().ContextSite;

                if (!string.IsNullOrEmpty(sp))
                {
                    if (sp.Equals(cmsMediaContentRepository.FindAllSpName, StringComparison.OrdinalIgnoreCase))
                    {
                        result = new { SiteGroupId = contextSite.SiteGroupId, SiteId = contextSite.Id };
                    }
                }

                return result ?? defaultParams;
            };
            container.Register<IEntityDataRepository<CmsMediaContent, int>>(cmsMediaContentRepository);
            container.Register(typeof(CmsMediaContentCreateCommand), typeof(CmsMediaContentCreateDataCommand));
            container.Register(typeof(CmsMediaContentFindByKeywordsCommand), typeof(CmsMediaContentFindByKeywordsDataCommand));
        }

        private static void SetCmsMedia(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsMedia>>(
                SqlEntityDataRepositoryConfiguration<CmsMedia, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsMedia))));
            container.Register<ISqlEntityDataMapper<CmsMedia, int>>(new CmsMediaDataMapper());
            var cmsMediaRepository = SqlEntityDataRepositoryConfiguration<CmsMedia, int>.CreateRepository();
            cmsMediaRepository.AddSpName = "cms_sp_MediaAdd";
            cmsMediaRepository.UpdateSpName = "cms_sp_MediaSave";
            cmsMediaRepository.RemoveSpName = "cms_sp_MediaDelete";
            container.Register<IEntityDataRepository<CmsMedia, int>>(cmsMediaRepository);
            container.Register(typeof(CmsMediaSelectOneCommand), typeof(CmsMediaSelectOneDataCommand));
            container.Register(typeof(CmsMediaSelectAllCommand), typeof(CmsMediaSelectAllDataCommand));
        }

        private static void SetCmsMediaFile(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsMediaFile>>(
                SqlEntityDataRepositoryConfiguration<CmsMediaFile, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsMediaFile))));
            container.Register<ISqlEntityDataMapper<CmsMediaFile, int>>(new CmsMediaFileDataMapper());
            var cmsMediaFileRepository = SqlEntityDataRepositoryConfiguration<CmsMediaFile, int>.CreateRepository();
            cmsMediaFileRepository.AddSpName = "cms_sp_MediaFileAdd";
            cmsMediaFileRepository.UpdateSpName = "cms_sp_MediaFileSave";
            cmsMediaFileRepository.FindAllSpName = "cms_sp_MediaFileSelectAll";
            cmsMediaFileRepository.RemoveSpName = "cms_sp_MediaFileDelete";
            cmsMediaFileRepository.FindParameters =
            (sp, defaultParams) =>
            {
                object result = null;

                var contextSite = DependencyServiceLocator.Current.GetInstance<ICmsContext>().ContextSite;

                if (!string.IsNullOrEmpty(sp))
                {
                    if (sp.Equals(cmsMediaFileRepository.FindAllSpName, StringComparison.OrdinalIgnoreCase))
                    {
                        result = new { SiteGroupId = contextSite.SiteGroupId, SiteId = contextSite.Id };
                    }
                }

                return result ?? defaultParams;
            };
            container.Register<IEntityDataRepository<CmsMediaFile, int>>(cmsMediaFileRepository);
            container.Register(typeof(CmsMediaFileSelectOneCommand), typeof(CmsMediaFileSelectOneDataCommand));
            container.Register(typeof(CmsMediaFileSelectByFolderIdsCommand), typeof(CmsMediaFileSelectByFolderIdsDataCommand));
            container.Register(typeof(CmsMediaFileRemoveByIdsCommand), typeof(CmsMediaFileRemoveByIdsDataCommand));
        }

        private static void SetCmsMediaContentFileLink(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsMediaContentFileLink>>(
                SqlEntityDataRepositoryConfiguration<CmsMediaContentFileLink, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsMediaContentFileLink))));
            container.Register<ISqlEntityDataMapper<CmsMediaContentFileLink, int>>(
                SqlEntityDataRepositoryConfiguration<CmsMediaContentFileLink, int>.CreateMapper(new string[] { "MediaContent", "MediaFile" }));

            var cmsMediaContentFileLinkRepository = SqlEntityDataRepositoryConfiguration<CmsMediaContentFileLink, int>.CreateRepository();
            cmsMediaContentFileLinkRepository.AddSpName = "cms_sp_MediaContentFileLinkAdd";
            container.Register<IEntityDataRepository<CmsMediaContentFileLink, int>>(cmsMediaContentFileLinkRepository);
        }

        private static void SetCmsMediaContentTag(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsMediaContentTag>>(
                SqlEntityDataRepositoryConfiguration<CmsMediaContentTag, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsMediaContentTag))));
            var cmsMediaContentTypeRepository = SqlEntityDataRepositoryConfiguration<CmsMediaContentTag, int>.CreateRepository();
            cmsMediaContentTypeRepository.AddSpName = "cms_sp_MediaContentTagAdd";
            cmsMediaContentTypeRepository.UpdateSpName = "cms_sp_MediaContentTagSave";
            cmsMediaContentTypeRepository.RemoveSpName = "cms_sp_MediaContentTagDelete";
            cmsMediaContentTypeRepository.FindOneSpName = "cms_sp_MediaContentTagSelectOne";
            cmsMediaContentTypeRepository.FindAllSpName = "cms_sp_MediaContentTagSelectAll";
            container.Register<IEntityDataRepository<CmsMediaContentTag, int>>(cmsMediaContentTypeRepository);
        }

        private static void SetCmsMimetype(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsMimeType>>(
                SqlEntityDataRepositoryConfiguration<CmsMimeType, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsMimeType))));
            var cmsMimeTypeRepository = SqlEntityDataRepositoryConfiguration<CmsMimeType, int>.CreateRepository();
            container.Register<IEntityDataRepository<CmsMimeType, int>>(cmsMimeTypeRepository);
            cmsMimeTypeRepository.AddSpName = "cms_sp_MimeTypeAdd";
            cmsMimeTypeRepository.FindAllSpName = "cms_sp_MimeTypeSelectAll";
            container.Register(typeof(CmsMimeTypeGetForContentTypeCommand), typeof(CmsMimeTypeGetForContentTypeDataCommand));
        }

        private static void SetCmsEntityMetaInformation(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsEntityMetaInformation>>(
                SqlEntityDataRepositoryConfiguration<CmsEntityMetaInformation, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsEntityMetaInformation))));
            container.Register<ISqlEntityDataMapper<CmsEntityMetaInformation, int>>(
                new CmsEntityMetaInformationDataMapper());
            container.Register<IEntityDataRepository<CmsEntityMetaInformation, int>>(
                SqlEntityDataRepositoryConfiguration<CmsEntityMetaInformation, int>.CreateRepository());
            container.Register(typeof(CmsEntityMetaGetInformationCommand), typeof(CmsEntityMetaGetInformationDataCommand));
        }

        private static void SetCmsEntityMeta(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsEntityMeta>>(
                SqlEntityDataRepositoryConfiguration<CmsEntityMeta, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsEntityMeta))));
            container.Register<ISqlEntityDataMapper<CmsEntityMeta, int>>(
                SqlEntityDataRepositoryConfiguration<CmsEntityMeta, int>.CreateMapper(
                    new string[] { "EntityMetaFieldLink", "IsDefault", "MetaFieldName" }));
            var cmsEntityMetaRepository = SqlEntityDataRepositoryConfiguration<CmsEntityMeta, int>.CreateRepository();
            cmsEntityMetaRepository.AddSpName = "cms_sp_EntityMetaAdd";
            cmsEntityMetaRepository.UpdateSpName = "cms_sp_EntityMetaSave";
            cmsEntityMetaRepository.RemoveSpName = "cms_sp_EntityMetaDelete";
            container.Register<IEntityDataRepository<CmsEntityMeta, int>>(cmsEntityMetaRepository);
        }

        private static void SetCmsEntityMetaField(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsEntityMetaField>>(
                SqlEntityDataRepositoryConfiguration<CmsEntityMetaField, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsEntityMetaField))));
            container.Register<ISqlEntityDataMapper<CmsEntityMetaField, int>>(new CmsEntityPropertyDataMapper());
            var cmsEntityMetaFieldRepository = SqlEntityDataRepositoryConfiguration<CmsEntityMetaField, int>.CreateRepository();
            cmsEntityMetaFieldRepository.AddSpName = "cms_sp_EntityMetaFieldAdd";
            cmsEntityMetaFieldRepository.FindAllSpName = "cms_sp_EntityMetaFieldSelectAll";
            cmsEntityMetaFieldRepository.FindOneSpName = "cms_sp_EntityMetaFieldSelectOne";
            cmsEntityMetaFieldRepository.UpdateSpName = "cms_sp_EntityMetaFieldSave";
            container.Register<IEntityDataRepository<CmsEntityMetaField, int>>(cmsEntityMetaFieldRepository);
            container.Register(typeof(CmsMetaFieldGetByNameAndEntityTypeCommand), typeof(CmsMetaFieldGetByNameAndEntityTypeDataCommand));
            container.Register(typeof(CmsEntityPropertyCreateCommand), typeof(CmsEntityPropertyCreateDataCommand));
        }

        private static void SetCmsUserInformation(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsUserInformation>>(
                SqlEntityDataRepositoryConfiguration<CmsUserInformation, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsUserInformation))));
            container.Register<IEntityDataRepository<CmsUserInformation, int>>(
                SqlEntityDataRepositoryConfiguration<CmsUserInformation, int>.CreateRepository());
            container.Register(typeof(CmsUserGetInformationCommand), typeof(CmsUserGetInformationDataCommand));
            container.Register(typeof(CmsUserInformationForManagementCommand), typeof(CmsUserInformationForManagementDataCommand));
            container.Register(typeof(CmsCreateUpdateUserCommand), typeof(CmsCreateUpdateUserAndAssignGroupsDataCommand));
            container.Register(typeof(CmsUserAssignToGroupsCommand), typeof(CmsUserAssignToGroupsDataCommand));
        }

        private static void SetCmsUser(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsUser>>(
                SqlEntityDataRepositoryConfiguration<CmsUser, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsUser))));
            var cmsUserDataRepository = SqlEntityDataRepositoryConfiguration<CmsUser, int>.CreateRepository();
            cmsUserDataRepository.RemoveSpName = "cms_sp_UserDelete";
            cmsUserDataRepository.FindAllSpName = "cms_sp_UserSelectAll";
            container.Register<IEntityDataRepository<CmsUser, int>>(cmsUserDataRepository);
            container.Register(typeof(CmsUserGetByUserGroupCommand), typeof(CmsUserGetByUserGroupDataCommand));
            container.Register(typeof(CmsUserGetByEmailCommand), typeof(CmsUserGetByEmailDataCommand));
        }

        private static void SetCmsUserGroup(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsUserGroup>>(
                SqlEntityDataRepositoryConfiguration<CmsUserGroup, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsUserGroup))));
            container.Register<ISqlEntityDataMapper<CmsUserGroup, int>>(
                new CmsUserGroupDataMapper(new string[] { "SiteGroup", "Site", "SiteCategory" }));
            var cmsUserGroupDataRepository = SqlEntityDataRepositoryConfiguration<CmsUserGroup, int>.CreateRepository();
            cmsUserGroupDataRepository.FindOneSpName = "cms_sp_UserGroupSelectOne";
            cmsUserGroupDataRepository.FindAllSpName = "cms_sp_UserGroupSelectAll";
            cmsUserGroupDataRepository.AddSpName = "cms_sp_UserGroupAdd";
            cmsUserGroupDataRepository.UpdateSpName = "cms_sp_UserGroupSave";
            cmsUserGroupDataRepository.RemoveSpName = "cms_sp_UserGroupDelete";
            container.Register<IEntityDataRepository<CmsUserGroup, int>>(cmsUserGroupDataRepository);
        }

        private static void SetCmsSite(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsSite>>(
                SqlEntityDataRepositoryConfiguration<CmsSite, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsSite))));
            container.Register<ISqlEntityDataMapper<CmsSite, int>>(
                SqlEntityDataRepositoryConfiguration<CmsSite, int>.CreateMapper(new string[] { "SiteGroup", "EntityMetaInformation" }));
            var cmsSiteDataRepository = SqlEntityDataRepositoryConfiguration<CmsSite, int>.CreateRepository();
            cmsSiteDataRepository.FindAllSpName = "cms_sp_SiteSelectAll";
            cmsSiteDataRepository.FindOneSpName = "cms_sp_SiteSelectOne";
            cmsSiteDataRepository.UpdateSpName = "cms_sp_SiteSave";
            cmsSiteDataRepository.AddSpName = "cms_sp_SiteAdd";
            container.Register<IEntityDataRepository<CmsSite, int>>(cmsSiteDataRepository);
            container.Register(typeof(CmsSiteSelectForUserCommand), typeof(CmsSiteSelectForUserDataCommand));
            container.Register(typeof(CmsSiteSelectForHostnameCommand), typeof(CmsSiteSelectForHostnameDataCommand));
        }

        private static void SetCmsDomain(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsDomain>>(
                SqlEntityDataRepositoryConfiguration<CmsDomain, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsDomain))));
            container.Register<ISqlEntityDataMapper<CmsDomain, int>>(
                SqlEntityDataRepositoryConfiguration<CmsDomain, int>.CreateMapper(new string[] { "Site", "EntityMetaInformation" }));
            var cmsDomainDataRepository = SqlEntityDataRepositoryConfiguration<CmsDomain, int>.CreateRepository();
            cmsDomainDataRepository.FindAllSpName = "cms_sp_DomainSelectAll";
            cmsDomainDataRepository.FindOneSpName = "cms_sp_DomainSelectOne";
            cmsDomainDataRepository.AddSpName = "cms_sp_DomainAdd";
            cmsDomainDataRepository.RemoveSpName = "cms_sp_DomainDelete";

            container.Register<IEntityDataRepository<CmsDomain, int>>(cmsDomainDataRepository);
            container.Register(typeof(CmsDomainGetBySiteIdCommand), typeof(CmsDomainGetBySiteIdDataCommand));
        }

        private static void SetCmsSiteGroup(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsSiteGroup>>(
                SqlEntityDataRepositoryConfiguration<CmsSiteGroup, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsSiteGroup))));
            var cmsSiteGroupDataRepository = SqlEntityDataRepositoryConfiguration<CmsSiteGroup, int>.CreateRepository();
            cmsSiteGroupDataRepository.FindOneSpName = "cms_sp_SiteGroupSelectOne";
            cmsSiteGroupDataRepository.FindAllSpName = "cms_sp_SiteGroupSelectAll";
            container.Register<IEntityDataRepository<CmsSiteGroup, int>>(cmsSiteGroupDataRepository);
        }

        private static void SetCmsSiteAdminMap(Func<Type, string> dataConnectionResolver)
        {
            var container = DependencyServiceLocator.Current;

            container.Register<IUnitOfWorkFactory<CmsSiteAdminMap>>(
                SqlEntityDataRepositoryConfiguration<CmsSiteAdminMap, int>.CreateUnitOfWorkFactory(dataConnectionResolver(typeof(CmsSiteAdminMap))));
            container.Register<ISqlEntityDataMapper<CmsSiteAdminMap, int>>(
                SqlEntityDataRepositoryConfiguration<CmsSiteAdminMap, int>.CreateMapper(new string[] { "Level", "HasChildren" }));
            var cmsSiteAdminMapDataRepository = SqlEntityDataRepositoryConfiguration<CmsSiteAdminMap, int>.CreateRepository();
            cmsSiteAdminMapDataRepository.FindAllSpName = "cms_sp_SiteAdminMapSelectAll";
            cmsSiteAdminMapDataRepository.FindOneSpName = "cms_sp_SiteAdminMapSelectOne";
            cmsSiteAdminMapDataRepository.AddSpName = "cms_sp_SiteAdminMapCreate";
            cmsSiteAdminMapDataRepository.UpdateSpName = "cms_sp_SiteAdminMapSave";
            cmsSiteAdminMapDataRepository.RemoveSpName = "cms_sp_SiteAdminMapDelete";
            container.Register<IEntityDataRepository<CmsSiteAdminMap, int>>(cmsSiteAdminMapDataRepository);
            container.Register(typeof(CmsSiteAdminMapSelectForUserCommand), typeof(CmsSiteAdminMapSelectForUserDataCommand));
        }
    }
}